using System;
using System.Collections.Generic;
using System.Text;
using Barrage.GUI.Meshes;
using Barrage.Textures;
using Barrage.GUI.Elements;
using System.Xml;
using Barrage.Meshes.Text;
using SlimDX;
using Barrage.Global;
using System.Globalization;

namespace Barrage.GUI.Templates.Standard
{
    struct StandardGUIButtonListAttributes
    {
        const string XML_TEXTURE_ATTRIBUTE = "texture";
        const string XML_PADDING_ATTRIBUTE = "padding";
        const string XML_BORDER_ATTRIBUTE = "border";
        const string XML_FONTSIZE_ATTRIBUTE = "fontSize";
        const string XML_TITLE_OFFSETX_ATTRIBUTE = "titleOffsetX";
        const string XML_TITLE_OFFSETY_ATTRIBUTE = "titleOffsetY";
        
        public string Texture;
        public string CoordBorder;
        public string UVBorder;
        public string BitmapFont;
        public float FontSize;
        public Vector2 TitleOffset;

        const string DEFAULT_TEXTURE = "Standard/buttonList.png";
        const string DEFAULT_COORDBORDER = "64,115,64,67";
        const string DEFAULT_UVBORDER = "0.0625,0.224609375,0.0625,0.130859375";
        const string DEFAULT_FONT = "Standard";
        const float DEFAULT_FONTSIZE = 24;
        const float DEFAULT_OFFSET_X = 64;
        const float DEFAULT_OFFSET_Y = -35;

        
        public static StandardGUIButtonListAttributes DefaultValues
        {
            get
            {
                return new StandardGUIButtonListAttributes(
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE,
                    DEFAULT_COORDBORDER,
                    DEFAULT_UVBORDER,
                    DEFAULT_FONT,
                    DEFAULT_FONTSIZE,
                    new Vector2(DEFAULT_OFFSET_X,DEFAULT_OFFSET_Y)
                    );
            }
        }

        public StandardGUIButtonListAttributes(string texture, string coordBorder, string UVBorder, string BitmapFont, float FontSize,Vector2 titleOffset)
        {
            this.Texture = texture;
            this.CoordBorder = coordBorder;
            this.UVBorder = UVBorder;
            this.BitmapFont = BitmapFont;
            this.FontSize = FontSize;
            this.TitleOffset=titleOffset;
        }
        public StandardGUIButtonListAttributes(XmlNode xn)
        {
            Texture = XmlHelper.GetXMLAttribute(xn, XML_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE);
            CoordBorder = XmlHelper.GetXMLAttribute(xn, XML_PADDING_ATTRIBUTE, DEFAULT_COORDBORDER);
            UVBorder = XmlHelper.GetXMLAttribute(xn, XML_BORDER_ATTRIBUTE, DEFAULT_UVBORDER);
            BitmapFont = DEFAULT_FONT;
            FontSize = XmlHelper.ParseXMLFloatAttribute(xn, XML_FONTSIZE_ATTRIBUTE, DEFAULT_FONTSIZE);
            TitleOffset = XmlHelper.ParseXMLVector2Attribute(xn, XML_TITLE_OFFSETX_ATTRIBUTE, XML_TITLE_OFFSETY_ATTRIBUTE, new Vector2(DEFAULT_OFFSET_X, DEFAULT_OFFSET_Y));
        }
    }
    /// <summary>
    /// Standard template implementation of GUIButtonList
    /// </summary>
    public class StandardGUIButtonList : GUIButtonList
    {
        const string XML_DEFAULT_ATTRIBUTE = "default";

        /// <summary>
        /// \internal Size of the item for mouse intersection checking. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSize { get { return new Vector2(500, 170); } }
        
        TextMesh titleMesh;

        StandardGUIButtonListAttributes attributes;

        float[] coordBorder;
        float[] uvBorder;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="layout">Layout that will hold this item</param>
        /// <param name="xn">Xml Node that holds attribute values of this item</param>
        public StandardGUIButtonList(GUILayout layout, XmlNode xn)
            : base(layout, GUITemplateTypes.Standard, xn)
        {
            processDefaultValues(xn);
            
            coordBorder = parseBorders(attributes.CoordBorder);
            uvBorder = parseBorders(attributes.UVBorder);

            addMesh(new BorderedRectangle(TextureManager.Textures[attributes.Texture],Size,coordBorder,uvBorder));
            
            BitmapFont f=BitmapFontManager.Fonts[attributes.BitmapFont];
            float scale=attributes.FontSize/f.FontInfo.LineHeight;
            
            titleMesh = new TextMesh(f, new TextDrawProperties( scale,attributes.TitleOffset));
            titleMesh.Text = Title;
            addMesh(titleMesh);
            
            // Modify options center
            for (int i = 0; i < Options.Count; i++)
            {
                Options[i].Motion.Translation += new Vector3(0, (coordBorder[3] - coordBorder[1] )/2.0f, 0);
            }
        }

        /// <summary>
        /// \internal Get / Set button list's title
        /// </summary>
        public override string Title { set { titleMesh.Text = value; base.Title = value; } }

        float[] parseBorders(string source)
        {
            float[] border= new float[4]{0,0,0,0};
            if (source == null) return border;
            string [] borderStrings = source.Split(',');
            for (int i = 0; i < Math.Min(4, borderStrings.Length); i++)
            {
                Single.TryParse(borderStrings[i], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out border[i]);
            }
            return border;
        }

        void processDefaultValues(XmlNode xn)
        {
            bool loadDefaults = XmlHelper.GetXMLAttribute(xn, XML_DEFAULT_ATTRIBUTE).Equals("true");
            if (loadDefaults)
                attributes = StandardGUIButtonListAttributes.DefaultValues;
            else
                attributes = new StandardGUIButtonListAttributes(xn);

        }

        /// <summary>
        /// \internal Updates item's matrices and meshes
        /// </summary>
        protected override void DoUpdate()
        {
            base.DoUpdate();
            titleMesh.Offset = attributes.TitleOffset + new Vector2(-Size.X / 2.0f, Size.Y / 2f);
            
        }

        /// <summary>
        /// \internal Clear resources
        /// </summary>
        public override void Dispose()
        {
            titleMesh = null;
            base.Dispose();
        }

        
    }
}
